package service

type StepChildren struct {
}

type StepWithChildren struct {
	Step
	Children []*StepWithChildren `json:"parent"`
}

type StepChildrenResItem struct {
	Step
	Level int
}

// 查询工序下游
func findChildren(stepParentMap map[int64]*StepWithChildren, findIdList []int64, children *[]StepChildrenResItem, level int, maxLevel int) {

	if maxLevel > 0 && level == maxLevel || len(findIdList) == 0 {
		return
	}
	var nextFindIdList = make([]int64, 0)

	for _, i := range findIdList {
		if _, ok := stepParentMap[i]; !ok {
			continue
		}
		if len(stepParentMap[i].Children) > 0 {
			for _, withParent := range stepParentMap[i].Children {
				*children = append(*children, StepChildrenResItem{
					Step: Step{
						Id:    withParent.Id,
						Name:  withParent.Name,
						Code:  withParent.Code,
						Color: withParent.Color,
					},
					Level: level,
				})
				nextFindIdList = append(nextFindIdList, withParent.Id)
			}
		}
	}
	if len(nextFindIdList) > 0 {
		findChildren(stepParentMap, nextFindIdList, children, level+1, maxLevel)
	}
}

// getStepWithChildrenMap 获得一个包含父级关系的工序map
func getStepWithChildrenMap(projectTemplateId int64) (res map[int64]*StepWithChildren, err error) {
	stepRelationList, err := getStepUpstreamRelationData(projectTemplateId)
	if err != nil {
		return
	}

	var stepMap = make(map[int64]bool, 0)
	var stepWithChildrenList = make([]StepWithChildren, 0)
	res = make(map[int64]*StepWithChildren)

	for _, s := range stepRelationList {
		if _, ok := stepMap[s.Id]; !ok {
			stepMap[s.Id] = true
			stepWithChildrenList = append(stepWithChildrenList, StepWithChildren{
				Step: Step{
					Id:    s.Id,
					Name:  s.Name,
					Code:  s.Code,
					Color: s.Color,
				},
			})
		}
	}

	// 创建一个stepList的 map reference
	for i, v := range stepWithChildrenList {
		res[v.Id] = &stepWithChildrenList[i]
	}

	// 关联父级关系
	for _, s := range stepRelationList {
		if s.ParentId > 0 {
			if _, ok := res[s.ParentId]; ok {
				res[s.ParentId].Children = append(res[s.ParentId].Children, res[s.Id])
			}
		}
	}
	return
}

// GetStepParents 查询单个工序的所有上游
func GetStepChildren(projectTemplateId int64, stepId int64) (res []StepChildrenResItem, err error) {
	stepWithParentRelation, err := getStepWithChildrenMap(projectTemplateId)
	if err != nil {
		return
	}
	findChildren(stepWithParentRelation, []int64{stepId}, &res, 0, 30)
	return
}

// GetStepsChildren 查询单个工序的所有下游
func GetStepsChildren(projectTemplateId int64, stepIdList []int64, maxLevel int) (res map[int64][]Step, err error) {
	stepWithChildrenRelation, err := getStepWithChildrenMap(projectTemplateId)
	if err != nil {
		return
	}
	res = make(map[int64][]Step, 0)
	for _, i := range stepIdList {
		var childrenMap = make(map[int64]bool, 0)
		var stepChildrenResult = make([]StepChildrenResItem, 0)
		findChildren(stepWithChildrenRelation, []int64{i}, &stepChildrenResult, 0, maxLevel)
		var childrenStepList = make([]Step, 0)
		for _, item := range stepChildrenResult {
			if ok, _ := childrenMap[item.Id]; !ok {
				childrenStepList = append(childrenStepList, Step{
					Id:    item.Id,
					Name:  item.Name,
					Code:  item.Code,
					Color: item.Color,
				})
				childrenMap[item.Id] = true
			}
		}
		res[i] = childrenStepList
	}

	return
}

// GetStepsChildren 查询单个工序的所有下游
func GetMultiProjectStepsChildren(projectTemplateMap map[int64]int64, projectStepIdList map[int64]map[int64]int64, maxLevel int) (res map[int64]map[int64][]Step, err error) {
	res = make(map[int64]map[int64][]Step, 0)
	for projectId, projectTemplateId := range projectTemplateMap {
		if _, projectOk := projectStepIdList[projectId]; !projectOk {
			continue
		}

		stepWithChildrenRelation, err := getStepWithChildrenMap(projectTemplateId)
		if err != nil {
			return res, err
		}

		var stepMap = make(map[int64][]Step, 0)
		for _, i := range projectStepIdList[projectId] {
			var childrenMap = make(map[int64]bool, 0)
			var stepChildrenResult = make([]StepChildrenResItem, 0)
			findChildren(stepWithChildrenRelation, []int64{i}, &stepChildrenResult, 0, maxLevel)
			var childrenStepList = make([]Step, 0)
			for _, item := range stepChildrenResult {
				if ok, _ := childrenMap[item.Id]; !ok {
					childrenStepList = append(childrenStepList, Step{
						Id:    item.Id,
						Name:  item.Name,
						Code:  item.Code,
						Color: item.Color,
					})
					childrenMap[item.Id] = true
				}
			}

			stepMap[i] = childrenStepList
		}
		res[projectId] = stepMap
	}

	return
}
